from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from django.conf import settings


class FastDFSStorage(Storage):
    """自定义文件储存方案：将文件转存到FDFS"""

    def __init__(self, client_conf=None,base_url=None):
        self.client_conf = client_conf or settings.FDFS_CLIENT_CONF
        self.base_url = base_url or settings.FDFS_BASE_URL


    def _open(self,name,mode='rb'):
        """
        打开文件是被调用的
        这个自定义的类是作文件的储存的，不会涉及到文件的打开，所以没有实际的用处，但是文档要求必须实现，所以pass
        :param name:
        :param mode:
        :return:
        """
        pass

    def _save(self, name, content):
        """
        保存文件是被调用的
        就是要节这个方法被调用的时机，将发送给django的文件储存到fastdfs
        :param name: 要保存的文件的名字
        :param content: 要保存的文件对象，file类型的对象，通过read（）读取文件存储的文件二进制
        :return: file-id
        """
        #  创建client
        #  client = Fdfs_client('meiduo_mall/utils/fastdfs/client.conf')
        client = Fdfs_client(self.client_conf)

        # 调用上传的方法：upload_by_buffer('文件二进制’）利用要保存的文件的二进制上传到fdfs
        ret = client.upload_by_buffer(content.read())

        # 判断收藏是否成功
        if ret.get('Status') != 'Upload successed.':
            raise Exception('fastdfs upload error')

        # 读取file-id
        file_id = ret.get('Remote file_id')
        # 返回file-id
        # _save()的返回值，会自动的存储存储ImageField字段对应的模型类属性中，并自动的同步到数据库
        return file_id

    def exists(self, name):
        """
        如果文件以存在就返回True，那么文件不在存储，save（）方法不在被调用
        :param name:判断文件是否存在的名字
        :return:False；告诉django，要保存的那么对应的文件不存在，就会调用save（）
        """
        return False

    def url(self, name):
        """
        返回文件的相对路径
        :param name: 文件的名字：group1/M00/00/00/wKhnhFtWOgCAZwjTAAExf6lt6Ck2361686
        :return:
        """
        return self.base_url + name








